//
//  KYCuteView.m
//  KYCuteViewDemo
//
//  Created by Kitten Yang on 2/26/15.
//  Copyright (c) 2015 Kitten Yang. All rights reserved.
//


#import "KYCuteView.h"

@implementation KYCuteView{
    
    UIBezierPath *cutePath;
    UIColor *fillColorForCute;
    UIDynamicAnimator *animator;
    UISnapBehavior  *snap;
    
    CADisplayLink *displayLink;
    

//    UIView *frontView;
    UIView *backView;
    CGFloat r1; // backView
    CGFloat r2; // frontView
    CGFloat x1;
    CGFloat y1;
    CGFloat x2;
    CGFloat y2;
    CGFloat centerDistance;
    CGFloat cosDigree;
    CGFloat sinDigree;
    
    CGPoint pointA; //A
    CGPoint pointB; //B
    CGPoint pointD; //D
    CGPoint pointC; //C
    CGPoint pointO; //O
    CGPoint pointP; //P
    
    CGRect oldBackViewFrame;
    CGPoint initialPoint;
    CGPoint oldBackViewCenter;
    CAShapeLayer *shapeLayer;
    
    CGFloat oldR1 ;
    CGPoint currentPosition;
}

-(id)initWithPoint:(CGPoint)point superView:(UIView *)view{
    self = [super initWithFrame:CGRectMake(point.x, point.y, self.bubbleWidth, self.bubbleWidth)];
    if(self){
        
        initialPoint = point;
        self.containerView = view;
                
        [self.containerView addSubview:self];
        oldR1 = -1;
    }
    return self;
}


- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setUp];
        [self addGesture];
    }
    return self;
}


//每隔一帧刷新屏幕的定时器
-(void)displayLinkAction:(CADisplayLink *)dis{
    x1 = backView.center.x;
    y1 = backView.center.y;
//    x2 = self.frontView.center.x;
//    y2 = self.frontView.center.y;
    x2 = currentPosition.x;
    y2 = currentPosition.y;
    
    NSLog(@"%@",NSStringFromCGPoint(currentPosition));
    
    centerDistance = sqrtf((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
    if (centerDistance == 0) {
        cosDigree = 1;
        sinDigree = 0;
    }else{
        cosDigree = (y2-y1)/centerDistance;
        sinDigree = (x2-x1)/centerDistance;
    }
//    NSLog(@"%f", acosf(cosDigree));
    
    r1 = oldBackViewFrame.size.width / 2 - centerDistance/self.viscosity;
    if (oldR1 == -1)
        oldR1 = r1;
//    NSLog(@"%f",r1);
    pointA = CGPointMake(x1-r1*cosDigree, y1+r1*sinDigree);  // A
    pointB = CGPointMake(x1+r1*cosDigree, y1-r1*sinDigree); // B
    pointD = CGPointMake(x2-r2*cosDigree, y2+r2*sinDigree); // D
    pointC = CGPointMake(x2+r2*cosDigree, y2-r2*sinDigree);// C
    pointO = CGPointMake((pointA.x + (centerDistance / 2)*sinDigree) , (pointA.y + (centerDistance / 2)*cosDigree));
    pointP = CGPointMake((pointB.x + (centerDistance / 2)*sinDigree) , (pointB.y + (centerDistance / 2)*cosDigree));
    
    CGPoint p = pointO;
    CGPoint p1 = pointP;
    pointO = CGPointMake((p.x + (p1.x - p.x) * (1- (r1 - 6) / (oldR1 - 6))) , p.y + (p1.y - p.y) * (1- (r1 - 6) / (oldR1 - 6)) );
    pointP = CGPointMake((p.x + (p1.x - p.x) * (r1 - 6) / (oldR1 - 6) ), p.y + (p1.y - p.y) * (r1 - 6) / (oldR1 - 6) );
//    NSLog(@"%f",[self distanceFrom:pointO to:pointP]);
//    pointO = CGPointMake((pointO.x + pointP.x) *0.5, (pointO.y + pointP.y) * 0.5);
//    pointP = pointO;
    [self drawRect];
}

-(void)drawRect{
    
    
    backView.center = oldBackViewCenter;
    backView.bounds = CGRectMake(0, 0, r1*2, r1*2);
    backView.layer.cornerRadius = r1;

    [self.frontView setCenter:currentPosition];
    
    cutePath = [UIBezierPath bezierPath];
    [cutePath moveToPoint:pointA];
    [cutePath addQuadCurveToPoint:pointD controlPoint:pointO];
    [cutePath addLineToPoint:pointC];
    [cutePath addQuadCurveToPoint:pointB controlPoint:pointP];
    [cutePath moveToPoint:pointA];
    
    
    if (backView.hidden == NO) {
        shapeLayer.path = [cutePath CGPath];
        shapeLayer.fillColor = [fillColorForCute CGColor];
        [self.containerView.layer insertSublayer:shapeLayer below:self.frontView.layer];
        
    }
    
}


-(void)setUp{
    shapeLayer = [CAShapeLayer layer];
    
    self.backgroundColor = [UIColor clearColor];
    self.frontView = [[UIView alloc]initWithFrame:CGRectMake(initialPoint.x,initialPoint.y, self.bubbleWidth, self.bubbleWidth)];

    r2 = self.frontView.bounds.size.width / 2;
    self.frontView.layer.cornerRadius = r2;
    self.frontView.backgroundColor = self.bubbleColor;
    
    backView = [[UIView alloc]initWithFrame:self.frontView.frame];
    r1 = backView.bounds.size.width / 2;
    backView.layer.cornerRadius = r1;
    backView.backgroundColor = self.bubbleColor;
    
    
    self.bubbleLabel = [[UILabel alloc]init];
    self.bubbleLabel.frame = CGRectMake(0, 0, self.frontView.bounds.size.width, self.frontView.bounds.size.height);
    self.bubbleLabel.textColor = [UIColor whiteColor];
    self.bubbleLabel.textAlignment = NSTextAlignmentCenter;
    
    [self.frontView insertSubview:self.bubbleLabel atIndex:0];


    
    [self.containerView addSubview:backView];
    [self.containerView addSubview:self.frontView];
    
    
    x1 = backView.center.x;
    y1 = backView.center.y;
    x2 = self.frontView.center.x;
    y2 = self.frontView.center.y;
    
    
    pointA = CGPointMake(x1-r1,y1);   // A
    pointB = CGPointMake(x1+r1, y1);  // B
    pointD = CGPointMake(x2-r2, y2);  // D
    pointC = CGPointMake(x2+r2, y2);  // C
    pointO = CGPointMake(x1-r1,y1);   // O
    pointP = CGPointMake(x2+r2, y2);  // P
    
    oldBackViewFrame = backView.frame;
    oldBackViewCenter = backView.center;

    backView.hidden = YES;//为了看到frontView的气泡晃动效果，需要展示隐藏backView，这是因为初始状态，frontview和backview是重叠的状态，但是气泡晃动会改变frontview的位置，如果不隐藏下面的backview就看不到效果了
    
    [self AddAniamtionLikeGameCenterBubble];
}


-(void)addGesture{
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(dragMe:)];
    [self.frontView addGestureRecognizer:pan];

}


-(void)dragMe:(UIPanGestureRecognizer *)ges{
    CGPoint dragPoint = [ges locationInView:self.containerView];
    currentPosition = dragPoint;
    if (ges.state == UIGestureRecognizerStateBegan) {
        backView.hidden = NO;
        fillColorForCute = self.bubbleColor;
        [self RemoveAniamtionLikeGameCenterBubble];
        if (displayLink == nil) {
            displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkAction:)];
            [displayLink setFrameInterval:1];
            [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
        }

    }else if (ges.state == UIGestureRecognizerStateChanged){
//        self.frontView.center = dragPoint;
        NSLog(@"%f",r1);
        if ( r1 < 6) {
            fillColorForCute = [UIColor clearColor];
            backView.hidden = YES;
            [shapeLayer removeFromSuperlayer];
            [displayLink invalidate];
            displayLink = nil;
            self.frontView.center = dragPoint;
        }

    }else if (ges.state == UIGestureRecognizerStateEnded || ges.state ==UIGestureRecognizerStateCancelled || ges.state == UIGestureRecognizerStateFailed){
        if(displayLink != nil){
            backView.hidden = YES;
            fillColorForCute = [UIColor clearColor];
            [shapeLayer removeFromSuperlayer];
            currentPosition = oldBackViewCenter;
            [UIView animateWithDuration:0.5 delay:0.0f usingSpringWithDamping:0.4f initialSpringVelocity:0.0f options:UIViewAnimationOptionCurveEaseInOut animations:^{
                self.frontView.center = self->oldBackViewCenter;
            } completion:^(BOOL finished) {
                
                if (finished) {
                    [self AddAniamtionLikeGameCenterBubble];
                    [self->displayLink invalidate];
                    self->displayLink = nil;
                }
                
            }];
        }else{
            NSLog(@"断开了");
            //已经断开了，还要判断是否要复位
            float distance = [self distanceFrom:self.frontView.center to:backView.center];
            NSLog(@"%f",distance);
            if (distance < 40) {
                backView.hidden = YES;
                fillColorForCute = [UIColor clearColor];
                [shapeLayer removeFromSuperlayer];
                [UIView animateWithDuration:0.5 delay:0.0f usingSpringWithDamping:0.4f initialSpringVelocity:0.0f options:UIViewAnimationOptionCurveEaseInOut animations:^{
                    self.frontView.center = self->oldBackViewCenter;
                } completion:^(BOOL finished) {
                    if (finished) {
                        [self AddAniamtionLikeGameCenterBubble];
                        [self->displayLink invalidate];
                        self->displayLink = nil;
                    }
                }];
            }else{
                //真的消失了
                backView.hidden = YES;
                self.frontView.hidden = YES;
                if ([_delegate respondsToSelector:@selector(onUnPlug)]) {
                    [_delegate onUnPlug];
                }
            }
            
        }
    }
    
}

-(double) distanceFrom:(CGPoint) aPoint to:(CGPoint) bPoint{
    return sqrt((aPoint.x - bPoint.x) * (aPoint.x - bPoint.x) + (aPoint.y - bPoint.y) * (aPoint.y - bPoint.y));
}

//----类似GameCenter的气泡晃动动画------
-(void)AddAniamtionLikeGameCenterBubble{

    CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    pathAnimation.calculationMode = kCAAnimationPaced;
    pathAnimation.fillMode = kCAFillModeForwards;
    pathAnimation.removedOnCompletion = NO;
    pathAnimation.repeatCount = INFINITY;
    pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    pathAnimation.duration = 5.0;
    
    
    CGMutablePathRef curvedPath = CGPathCreateMutable();
    CGRect circleContainer = CGRectInset(self.frontView.frame, self.frontView.bounds.size.width / 2 - 3, self.frontView.bounds.size.width / 2 - 3);
    CGPathAddEllipseInRect(curvedPath, NULL, circleContainer);
    
    pathAnimation.path = curvedPath;
    CGPathRelease(curvedPath);
    [self.frontView.layer addAnimation:pathAnimation forKey:@"myCircleAnimation"];
    
    
    CAKeyframeAnimation *scaleX = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale.x"];
    scaleX.duration = 1;
    scaleX.values = @[@1.0, @1.1, @1.0];
    scaleX.keyTimes = @[@0.0, @0.5, @1.0];
    scaleX.repeatCount = INFINITY;
    scaleX.autoreverses = YES;

    scaleX.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self.frontView.layer addAnimation:scaleX forKey:@"scaleXAnimation"];
    

    CAKeyframeAnimation *scaleY = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale.y"];
    scaleY.duration = 1.5;
    scaleY.values = @[@1.0, @1.1, @1.0];
    scaleY.keyTimes = @[@0.0, @0.5, @1.0];
    scaleY.repeatCount = INFINITY;
    scaleY.autoreverses = YES;
    scaleX.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self.frontView.layer addAnimation:scaleY forKey:@"scaleYAnimation"];
}

-(void)RemoveAniamtionLikeGameCenterBubble{
    [self.frontView.layer removeAllAnimations];
}


@end
